#!/bin/bash

################################################################################
# MinIO 负载均衡测试脚本
# 功能: 测试 Nginx 负载均衡是否正常工作，请求是否分布到所有节点
# 使用: ./test-load-balance.sh [api|console] [请求次数]
################################################################################

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# 默认配置
DEFAULT_REQUESTS=100
DEFAULT_TARGET="api"

# MinIO 节点列表
NODES=("minio1" "minio2" "minio3" "minio4")
NODE_IPS=("10.1.1.103" "10.1.1.104" "10.1.1.105" "10.1.1.106")

# 显示使用帮助
show_usage() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 负载均衡测试脚本${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo -e "${YELLOW}使用方法:${NC}"
    echo -e "  $0 [api|console] [请求次数]"
    echo ""
    echo -e "${YELLOW}参数说明:${NC}"
    echo -e "  api       - 测试 API 端点 (端口 9100，默认)"
    echo -e "  console   - 测试 Console 端点 (端口 9190)"
    echo -e "  请求次数   - 发送的请求总数 (默认: ${DEFAULT_REQUESTS})"
    echo ""
    echo -e "${YELLOW}示例:${NC}"
    echo -e "  $0                  # 测试 API，发送 100 个请求"
    echo -e "  $0 api 200          # 测试 API，发送 200 个请求"
    echo -e "  $0 console 50       # 测试 Console，发送 50 个请求"
    echo ""
}

# 清空日志
clear_logs() {
    echo -e "${YELLOW}清空 MinIO 节点访问日志...${NC}"
    
    for node in "${NODES[@]}"; do
        # 清空 MinIO 日志（如果有的话）
        ssh ${node} "sudo truncate -s 0 /opt/linux_minio/log/minio-audit.log 2>/dev/null || true" &
    done
    
    wait
    echo -e "${GREEN}✅ 日志已清空${NC}"
    echo ""
}

# 发送测试请求
send_requests() {
    local target=$1
    local count=$2
    local url=""
    local endpoint=""
    
    if [ "$target" = "api" ]; then
        url="http://10.1.1.103:9100/minio/health/live"
        endpoint="API (9100)"
    else
        url="http://10.1.1.103:9190/"
        endpoint="Console (9190)"
    fi
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}开始负载均衡测试${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo -e "${YELLOW}测试目标:${NC} ${endpoint}"
    echo -e "${YELLOW}测试 URL:${NC} ${url}"
    echo -e "${YELLOW}请求次数:${NC} ${count}"
    echo ""
    
    echo -e "${YELLOW}发送请求中...${NC}"
    
    # 创建临时文件存储响应头
    TEMP_DIR=$(mktemp -d)
    
    # 发送请求
    for i in $(seq 1 $count); do
        curl -s -o /dev/null -D "${TEMP_DIR}/response_${i}.txt" "$url" &
        
        # 每 10 个请求显示一次进度
        if [ $((i % 10)) -eq 0 ]; then
            echo -ne "\r  进度: ${i}/${count} 请求已发送"
        fi
    done
    
    # 等待所有请求完成
    wait
    echo -e "\r  进度: ${count}/${count} 请求已发送 ${GREEN}✓${NC}"
    echo ""
    
    # 清理临时文件
    rm -rf ${TEMP_DIR}
    
    echo -e "${GREEN}✅ 请求发送完成${NC}"
    echo ""
}

# 分析 Nginx 访问日志
analyze_nginx_logs() {
    echo -e "${YELLOW}分析 Nginx 访问日志...${NC}"
    echo ""
    
    # 检查 Nginx 日志文件
    NGINX_LOG="/home/jd103/nginx-lb/logs/access.log"
    
    if [ ! -f "$NGINX_LOG" ]; then
        echo -e "${RED}错误: Nginx 日志文件不存在: ${NGINX_LOG}${NC}"
        return 1
    fi
    
    # 统计最近的请求
    echo -e "${CYAN}Nginx 请求统计 (最近 100 条):${NC}"
    tail -100 "$NGINX_LOG" | awk '{print $1}' | sort | uniq -c | sort -rn
    echo ""
}

# 检查各节点连接数
check_node_connections() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}检查各节点连接情况${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    printf "${CYAN}%-10s %-15s %-20s %-15s${NC}\n" "节点" "IP地址" "活跃连接数" "总连接数"
    echo "------------------------------------------------------------------------"
    
    for i in "${!NODES[@]}"; do
        node="${NODES[$i]}"
        ip="${NODE_IPS[$i]}"
        
        # 获取到 9000 端口的连接数
        active_conn=$(ssh ${node} "netstat -an | grep ':9000' | grep ESTABLISHED | wc -l" 2>/dev/null || echo "0")
        total_conn=$(ssh ${node} "netstat -an | grep ':9000' | wc -l" 2>/dev/null || echo "0")
        
        printf "%-10s %-15s %-20s %-15s\n" "${node}" "${ip}" "${active_conn}" "${total_conn}"
    done
    
    echo ""
}

# 分析 MinIO 审计日志
analyze_minio_logs() {
    local target=$1
    local port=""
    
    if [ "$target" = "api" ]; then
        port="9000"
    else
        port="9090"
    fi
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 节点请求分布统计${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    # 创建临时文件存储结果
    TEMP_RESULT=$(mktemp)
    
    echo -e "${YELLOW}正在收集各节点的请求日志...${NC}"
    echo ""
    
    # 收集每个节点的请求数
    declare -A node_requests
    total_requests=0
    
    for i in "${!NODES[@]}"; do
        node="${NODES[$i]}"
        
        # 统计最近的审计日志条目数（最近 5 分钟）
        count=$(ssh ${node} "tail -1000 /opt/linux_minio/log/minio-audit.log 2>/dev/null | wc -l" 2>/dev/null || echo "0")
        
        node_requests[$node]=$count
        total_requests=$((total_requests + count))
    done
    
    # 显示结果
    echo -e "${CYAN}节点请求分布:${NC}"
    echo ""
    printf "${CYAN}%-10s %-15s %-15s %-15s${NC}\n" "节点" "请求数" "百分比" "状态"
    echo "------------------------------------------------------------------------"
    
    for node in "${NODES[@]}"; do
        count=${node_requests[$node]}
        
        if [ $total_requests -gt 0 ]; then
            percentage=$(awk "BEGIN {printf \"%.2f\", ($count / $total_requests) * 100}")
        else
            percentage="0.00"
        fi
        
        # 判断分布是否均衡（理想值 25%，允许 ±10% 偏差）
        status="${GREEN}✓ 正常${NC}"
        if (( $(echo "$percentage < 15" | bc -l) )) || (( $(echo "$percentage > 35" | bc -l) )); then
            status="${YELLOW}⚠ 偏差${NC}"
        fi
        
        printf "%-10s %-15s %-15s %-15s\n" "${node}" "${count}" "${percentage}%" "$(echo -e ${status})"
    done
    
    echo ""
    echo -e "${CYAN}总请求数:${NC} ${total_requests}"
    echo ""
    
    # 评估负载均衡效果
    if [ $total_requests -gt 0 ]; then
        # 计算标准差
        avg=$(awk "BEGIN {printf \"%.2f\", $total_requests / 4}")
        
        echo -e "${YELLOW}负载均衡评估:${NC}"
        echo -e "  平均每节点: ${avg} 请求"
        echo -e "  理想分布: 25% 每节点"
        echo ""
        
        # 检查是否均衡
        balanced=true
        for node in "${NODES[@]}"; do
            count=${node_requests[$node]}
            percentage=$(awk "BEGIN {printf \"%.2f\", ($count / $total_requests) * 100}")
            
            if (( $(echo "$percentage < 15" | bc -l) )) || (( $(echo "$percentage > 35" | bc -l) )); then
                balanced=false
                break
            fi
        done
        
        if [ "$balanced" = true ]; then
            echo -e "${GREEN}✅ 负载均衡正常！请求均匀分布到所有节点${NC}"
        else
            echo -e "${YELLOW}⚠️  负载分布不均，可能需要检查配置${NC}"
        fi
    else
        echo -e "${RED}❌ 未检测到请求，请确保测试已执行${NC}"
    fi
    
    echo ""
    
    rm -f ${TEMP_RESULT}
}

# 实时监控请求分布
monitor_realtime() {
    local target=$1
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}实时监控请求分布 (Ctrl+C 退出)${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    while true; do
        clear
        echo -e "${CYAN}实时连接统计 - $(date '+%Y-%m-%d %H:%M:%S')${NC}"
        echo ""
        
        printf "${CYAN}%-10s %-15s %-20s${NC}\n" "节点" "IP地址" "活跃连接 (9000)"
        echo "--------------------------------------------------------"
        
        for i in "${!NODES[@]}"; do
            node="${NODES[$i]}"
            ip="${NODE_IPS[$i]}"
            
            active_conn=$(ssh ${node} "netstat -an | grep ':9000' | grep ESTABLISHED | wc -l" 2>/dev/null || echo "0")
            
            printf "%-10s %-15s %-20s\n" "${node}" "${ip}" "${active_conn}"
        done
        
        echo ""
        echo -e "${YELLOW}按 Ctrl+C 退出监控${NC}"
        
        sleep 2
    done
}

# 完整测试流程
full_test() {
    local target=$1
    local count=$2
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 负载均衡完整测试${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    # 1. 清空日志
    clear_logs
    
    # 2. 发送测试请求
    send_requests "$target" "$count"
    
    # 3. 等待日志写入
    echo -e "${YELLOW}等待 3 秒，让日志写入...${NC}"
    sleep 3
    echo ""
    
    # 4. 检查连接数
    check_node_connections
    
    # 5. 分析日志
    analyze_minio_logs "$target"
    
    # 6. 分析 Nginx 日志
    analyze_nginx_logs
    
    echo -e "${GREEN}========================================${NC}"
    echo -e "${GREEN}测试完成！${NC}"
    echo -e "${GREEN}========================================${NC}"
}

# 主程序
main() {
    # 解析参数
    TARGET=${1:-$DEFAULT_TARGET}
    COUNT=${2:-$DEFAULT_REQUESTS}
    
    # 验证参数
    if [ "$TARGET" != "api" ] && [ "$TARGET" != "console" ] && [ "$TARGET" != "monitor" ]; then
        echo -e "${RED}错误: 无效的目标 '${TARGET}'${NC}"
        echo ""
        show_usage
        exit 1
    fi
    
    # 检查请求次数是否为数字
    if ! [[ "$COUNT" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}错误: 请求次数必须是数字${NC}"
        echo ""
        show_usage
        exit 1
    fi
    
    # 特殊命令：实时监控
    if [ "$TARGET" = "monitor" ]; then
        monitor_realtime "api"
        exit 0
    fi
    
    # 执行完整测试
    full_test "$TARGET" "$COUNT"
}

# 执行主程序
main "$@"
